/**
 * 
 */
package com.dfhc.tag;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

import javax.servlet.ServletRequest;

import com.dfhc.PjException;
import com.dfhc.util.StringHelper;

/**
 * @author 龙色波
 * 动态字段tag 用于展示动态字段的工具类
 */
public class DynamicTagUtil {
	/**
	 * 标签堆栈
	 */
	private Stack<TagItem> tagStack = new Stack<TagItem>();
	/**
	 * 页面的请求对象
	 */
	private ServletRequest  servletRequest;
	/**
	 * 解析执行标签  允许嵌套
	 * @param tagSource
	 * @param parameterMap
	 * @return
	 */
	public String parseTags(String tagSource,Map parameterMap){
		int len =tagSource.length();
		
		int i=0;
		char ch;
		
		StringBuilder word=new StringBuilder();
		String body="";
		ParseDynamicTag parseDynamicTag = new ParseDynamicTag();  
		while(i<len){
			ch = tagSource.charAt(i);
			if(ch=='<'){
				//继续查找'>',找不到报错
				word.delete(0, word.length());
				word.append(ch);
				while(++i<len && ch!='>'){
					ch = tagSource.charAt(i);
					word.append(ch);

				}
				if(i>=len && !word.toString().endsWith(">")){
					throw new PjException("缺少>!");
				}
				String wordTemp = word.toString();
				//替换掉<后面空格或制表符
				while(StringHelper.findStrNum(wordTemp.toString(), "< ")>0||StringHelper.findStrNum(wordTemp.toString(), "<\t")>0){
				      wordTemp = StringHelper.replaceAll(wordTemp, "< ", "<").toString();	
				      wordTemp = StringHelper.replaceAll(wordTemp, "<\t", "<").toString();
				}
				//检查是否包含</...>或/>
				if(StringHelper.findStrNum(wordTemp, "</")>0||StringHelper.findStrNum(wordTemp, "/>")>0){
					TagItem top = null;
					//如果是/>这种，则先构造TagItem入栈
					if(StringHelper.findStrNum(wordTemp, "/>")>0){
						TagItem item = makeTagItem(wordTemp);
						tagStack.push(item);
					}
					//body先入栈,item后入栈
				   //循环出栈，直到遇到不是body类型的Tag
				   while(!tagStack.isEmpty()){
				    top = tagStack.pop();
				    if(top.getTagType().equals(TagItem.TAG_TYPE_BODY)){
				    	body = top.getBody()+body;
				    }else{
				    	break;
				    }
				   }
				   if(top==null){
					   throw new PjException("标签缺少开头<...>!");
				   }
				   if(top.getTagType().equals(TagItem.TAG_TYPE_BODY)){
					   return body;
				   }else{
					   //调用ParseDynamicTag处理标签
					   parseDynamicTag.setAttributesMap(top.getAttributesMap());
					   parseDynamicTag.setBody(body);
					   parseDynamicTag.setTagType(top.getTagType());
					   parseDynamicTag.setServletRequest(servletRequest);
					   body = parseDynamicTag.parse();
					   if(!StringHelper.isEmpty(body)){
					   //body转为tagItem入堆栈
					   TagItem item = makeTagItem(TagItem.TAG_TYPE_BODY);
					   item.setBody(body);
					   tagStack.push(item);
					   body="";
					   }
				   }
				}else{
					TagItem item = makeTagItem(word.toString());
					//body先入栈,item后入栈
					//body转为tagItem入堆栈
					if(!StringHelper.isEmpty(body)){
					    TagItem bodyItem = makeTagItem(TagItem.TAG_TYPE_BODY);
					    bodyItem.setBody(body);
					    tagStack.push(bodyItem);
					    body = "";
					}
				    tagStack.push(item);				    
				}
			}else{
				body = body+ch;
				i = i+1;
			}
		}
		TagItem top = null;
		while(!tagStack.isEmpty()){
		    top = tagStack.pop();
		    if(top.getTagType().equals(TagItem.TAG_TYPE_BODY)){
		    	body = top.getBody()+body;
		    }else{
		       //调用ParseDynamicTag处理标签		 
			   parseDynamicTag.setAttributesMap(top.getAttributesMap());
			   parseDynamicTag.setBody(body);
			   parseDynamicTag.setTagType(top.getTagType());
			   parseDynamicTag.setServletRequest(servletRequest);
			    
			   
			   TagItem bodyItem = makeTagItem(TagItem.TAG_TYPE_BODY);
			   bodyItem.setBody(parseDynamicTag.parse());
			   tagStack.push(bodyItem);
		    }
		}
		return body;
		   
	}
	/**
	 * 根据类型构造 tagItem
	 * @param itemType
	 * @return
	 */
	private TagItem makeTagItem(String itemType) {
		TagItem item = new TagItem();
		/**
		 * 按钮
		 */
		if(StringHelper.findStrIgnoreCase(itemType, TagItem.TAG_TYPE_BUTTON, 0)>=0){
			item.setTagType(TagItem.TAG_TYPE_BUTTON);
		}else
		/**
		 * checkbox
		 */
		if(StringHelper.findStrIgnoreCase(itemType, TagItem.TAG_TYPE_CHECKBOX,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_CHECKBOX);
		}else
		/**
		 * div
		 */
		if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_DIV,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_DIV);
		}else					
		/**
		 * input
		 */
		if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_INPUT,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_INPUT);
		}else
		/**
		 * label
		 */
		if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_LABEL,0)>=0){ 
			item.setTagType(TagItem.TAG_TYPE_LABEL);
		}else		
		/**
		 * pagesign
		 */
		if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_PAGESIGN,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_PAGESIGN);
		}else
		/**
		 * password
		 */
		if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_PASSWORD,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_PASSWORD);		
		/**
		 * radio
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_RADIO,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_RADIO);
		/**
		 * REGION
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_REGION,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_REGION);
		/**
		 * 下拉框
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_SELECT,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_SELECT);
		/**
		 * SPAN
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_SPAN,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_SPAN);
		/**
		 * 表格
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_TABLE,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_TABLE);
		/**
		 * TD
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_TD,0)>=0){ 
			item.setTagType(TagItem.TAG_TYPE_TD);
		/**
		 * 大编辑框
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_TEXTAREA,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_TEXTAREA);
		/**
		 * 表头
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_THEAD,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_THEAD);
		/**
		 * TH
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_TH,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_TH);
		/**
		 * TITLE
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_TITLE,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_TITLE);
		/**
		 * 树
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_TREE,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_TREE);
		/**
		 * TR
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_TR,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_TR);
		/**
		 * TAG_TYPE_BODY	
		 */
		}else if(StringHelper.findStrIgnoreCase(itemType,TagItem.TAG_TYPE_BODY,0)>=0){
			item.setTagType(TagItem.TAG_TYPE_BODY);			
		}else{
			throw new PjException("不支持的标签类型:"+itemType);
		}
		//构造中间参数,去掉类型及<,>
		String temp = StringHelper.replaceAllIgnoreCase(itemType, item.getTagType(), "");
		temp = StringHelper.replaceAll(temp, ">", "").toString();
		temp = StringHelper.replaceAll(temp, "<", "").toString();
		Map parameterMap = new HashMap();
		if(!StringHelper.isEmpty(temp)){
			//去掉等号前后空格
			while(StringHelper.findStrNum(temp, " =")>0||StringHelper.findStrNum(temp, "= ")>0){
				temp = StringHelper.replaceAll(temp, " =", "=").toString();
				temp = StringHelper.replaceAll(temp, "= ", "=").toString();
			}
			String parameters[] =StringHelper.splitString(temp, " ");
			
			if(parameters!=null){
				for(String parameter:parameters){
					int pos = StringHelper.findStrIgnoreCase(parameter, "=", 0);
					if(pos>0){
						String key = parameter.substring(0, pos);
						String value = parameter.substring(pos+1);
						//value去掉前后双引号
						value = value.trim();
						if(value.startsWith("\"")){
							value = value.substring(1);
						}
						if(value.endsWith("\"")){
							value = value.substring(0,value.length()-1);
						}
						parameterMap.put(key, value);	
					}
				}
			}
			
		}
		item.setAttributesMap(parameterMap);
		return item;
	}
	public ServletRequest getServletRequest() {
		return servletRequest;
	}
	public void setServletRequest(ServletRequest servletRequest) {
		this.servletRequest = servletRequest;
	}
}
